package com.module.imagelib.glide.strategy;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;
import com.module.imagelib.glide.LoaderOptions;
import com.module.imagelib.glide.callback.BitmapCallBack;
import com.module.imagelib.glide.callback.FileCallBack;
import com.module.imagelib.glide.progress.OnProgressListener;
import com.module.imagelib.glide.progress.ProgressManager;
import com.module.imagelib.glide.transfor.GlideCircleTransform;
import com.module.imagelib.glide.transfor.GlideRoundTransform;

import java.io.File;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
 * Created by JohnsonFan on 2017/6/27.
 */

public class GlideStrategy implements ILoaderStrategy {

    private Context mContext;

    public GlideStrategy(Context mContext) {
        this.mContext = mContext.getApplicationContext();
    }

    @Override
    public void clearMemoryCache() {
        Glide.get(mContext).clearMemory();
    }

    @Override
    public void clearDiskCache() {
        Glide.get(mContext).clearDiskCache();
    }

    @Override
    public void pauseRequests() {
        Glide.with(mContext).pauseRequests();
    }

    @Override
    public void resumeRequests() {
        Glide.with(mContext).resumeRequests();
    }

    @Override
    public void loadImage(LoaderOptions options) {
        RequestBuilder request = null;
        request = createRequests(options, request);

        if (request == null) {
            throw new NullPointerException("requestCreator must not be null");
        }
        if (options.bitmapHeight > 0 && options.bitmapWidth > 0) {
            request.override(options.bitmapWidth, options.bitmapHeight);
        }
        if (options.isCenterInside) {
            request.centerInside();
        } else if (options.isCenterCrop) {
            request.centerCrop();
        } else if (options.isCircle) {
            request.transform(new GlideCircleTransform());
        }
        if (options.onImageListener != null) {
            progressLoading(request, options);
        }
        if (options.errorResId != 0) {
            request.error(options.errorResId);
        }
        if (options.placeholderResId != 0) {
            request.placeholder(options.placeholderResId);
        }
        if (options.bitmapAngle != 0) {
            request.transform(new GlideRoundTransform(options.bitmapAngle));
        }
        if (options.skipMemoryCache) {
            request.skipMemoryCache(options.skipMemoryCache);
        }
        if (options.skipDiskCache) {
            request.diskCacheStrategy(DiskCacheStrategy.NONE);
        }
        if (options.targetView instanceof ImageView) {
            request.into(((ImageView) options.targetView));
        } else if (options.isFile && options.callBack instanceof FileCallBack) {
            final LoaderOptions finalOptions = options;
            request.into(new CustomTarget<File>() {
                @Override
                public void onResourceReady(@NonNull File resource, @Nullable Transition transition) {
                    finalOptions.callBack.onLoaded(resource);
                }

                @Override
                public void onLoadCleared(@Nullable Drawable placeholder) {

                }
            });
        } else if (options.isBitmap && options.callBack instanceof BitmapCallBack) {
            final LoaderOptions finalOptions = options;
            request.into(new CustomTarget<Bitmap>() {
                @Override
                public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) {
                    finalOptions.callBack.onLoaded(resource);
                }

                @Override
                public void onLoadCleared(@Nullable Drawable placeholder) {

                }
            });
        }

    }

    private RequestBuilder createRequests(LoaderOptions options, RequestBuilder request) {
        if (options.isFile) {
            if (options.url != null) {
                request = Glide.with(mContext).asFile().load(options.url);
            } else if (options.file != null) {
                request = Glide.with(mContext).asFile().load(options.file);
            } else if (options.drawableResId != 0) {
                request = Glide.with(mContext).asFile().load(options.drawableResId);
            } else if (options.uri != null) {
                request = Glide.with(mContext).asFile().load(options.uri);
            }
        } else if (options.isBitmap) {
            if (options.url != null) {
                request = Glide.with(mContext).asBitmap().load(options.url);
            } else if (options.file != null) {
                request = Glide.with(mContext).asBitmap().load(options.file);
            } else if (options.drawableResId != 0) {
                request = Glide.with(mContext).asBitmap().load(options.drawableResId);
            } else if (options.uri != null) {
                request = Glide.with(mContext).asBitmap().load(options.uri);
            }
        } else {
            if (options.url != null) {
                request = Glide.with(mContext).load(options.url);
            } else if (options.file != null) {
                request = Glide.with(mContext).load(options.file);
            } else if (options.drawableResId != 0) {
                request = Glide.with(mContext).load(options.drawableResId);
            } else if (options.uri != null) {
                request = Glide.with(mContext).load(options.uri);
            }
        }
        return request;
    }

    @SuppressWarnings("CheckResult")
    private void progressLoading(RequestBuilder request, final LoaderOptions options) {
        //RequestListener->OnImageListener
        final OnProgressListener internalProgressListener = new OnProgressListener() {
            @Override
            public void onProgress(String imageUrl, long bytesRead, long totalBytes, boolean isDone, GlideException exception) {
                int percent = (int) ((bytesRead * 1.0f / totalBytes) * 100.0f);
                options.onImageListener.onProgress(percent, isDone, exception);
            }
        };
        //注册监听
        ProgressManager.addProgressListener(internalProgressListener);
        //设置进度监听
        request.listener(new RequestListener() {
            @Override
            public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
                //加载失败添加回调
                options.onImageListener.onProgress(0, true, e);
                //删除监听
                ProgressManager.removeProgressListener(internalProgressListener);
                return false;
            }

            @Override
            public boolean onResourceReady(Object resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
                //加载成功添加回调
                options.onImageListener.onProgress(100, true, null);
                //删除监听
                ProgressManager.removeProgressListener(internalProgressListener);
                return false;
            }
        });
    }

}

